package classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader{
	
	private String name;
	private String path;
	
	public MyClassLoader(String name, String path) {
		super();
		this.name = name;
		this.path = path;
	}
	public MyClassLoader(ClassLoader parent,String name, String path) {
		super(parent);
		this.name = name;
		this.path = path;
	}
	
	@Override
	public Class<?> loadClass(String name) throws ClassNotFoundException {
		if(this.name.equals(name)){
			Class<?> c = findLoadedClass(name);
			if(c == null){
				c = super.loadClass(name);
				if(c == null){
					c = findClass(name);
				}
			}
		}
		return super.loadClass(name);
	}
	
	
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String classPath = converNameToPath(name);
		byte[] bytes = readClassFileToByte(classPath);
		if(bytes != null){
			return super.defineClass(name, bytes, 0, bytes.length);
		} 
		return null;
	}
	
	private byte[] readClassFileToByte(String classPath) {
		InputStream is = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		File file = new File(classPath);
		boolean b = file.exists();
		if(b){
			try {
				is = new FileInputStream(file);
				int len = 0;
				byte[] classContent = new byte[1024];
				while((len = is.read(classContent))<0){
					bos.write(classContent, 0, len);
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if(bos != null){
						bos.close();
					}
					if(is != null){
						is.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return bos.toByteArray();
	}
	/**
	 * 转义全限定类名为路径格式
	 * 如：com.demo  ---->  com/demo
	 * @param name 加载类的全限定名字
	 * @param path 类所在路径（不包括包） 
	 */
	private String converNameToPath(String name){
		String classPath = name.replaceAll("\\.", "/");
		return this.path+"/"+classPath+".class";
	}
	
	
	
	
}
